package com.wkk.utils;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wkk.exception.NoBugException;
import org.springframework.beans.BeanUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : WangKeKe
 * @date : 2020/9/29 10:07
 * Description : 工具包
 */


public class NoBugTools {

    private static final String EMPTY = "";

    private static final String EMPTY_NULL = "null";

    private static final String UNKNOWN = "unknown";

    private static final String X_FORWARDED_FOR = "x-forwarded-for";

    private static final String PROXY_CLIENT_IP = "Proxy-Client-IP";

    private static final String WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP";

    /**
     * 判断某个实体类是否为空
     *
     * @param object 实体信息
     * @return true:false
     */
    public static boolean isEmpty(Object object) {
        if (object == null) {
            return (true);
        }
        if (EMPTY.equals(object)) {
            return (true);
        }
        return EMPTY_NULL.equals(object);
    }

    /**
     * 判断某个实体类是否为不为空
     *
     * @param object 实体信息
     * @return true:false
     */
    public static boolean isNotEmpty(Object object) {
        return object != null && !object.equals(EMPTY) && !object.equals(EMPTY_NULL);
    }

    /**
     * 判断某个字符串为空
     *
     * @param str 字符串
     * @return true:false
     */
    public static boolean isEmpty(String str) {
        return str == null || str.equals(EMPTY);
    }


    /**
     * 判断某个字符串不为空
     *
     * @param str 字符串
     * @return true:false
     */
    public static boolean isNotEmpty(String str) {
        return str != null && !str.equals(EMPTY);
    }


    /**
     * 判断 list 是否为空
     *
     * @param list 集合
     * @return true or false
     * list == null		: true
     * list.size() == 0	: true
     */
    public static boolean listIsEmpty(Collection list) {
        return (list == null || list.size() == 0);
    }

    /**
     * 判断 list 是否不为空
     *
     * @param list 集合
     * @return true or false
     * list == null		: false
     * list.size() == 0	: false
     */
    public static boolean listIsNotEmpty(Collection list) {
        return !listIsEmpty(list);
    }


    /**
     * 将实体类F 转换成实体类T
     *
     * @param entity     实体类F
     * @param modelClass 实体类T的class
     * @return 实体类T
     */
    public static <F, T> T entityToModel(F entity, Class<T> modelClass) {
        T model;
        if (isEmpty(entity) || isEmpty(modelClass)) {
            return null;
        }
        try {
            // 通过反射获取对象
            model = modelClass.newInstance();
        } catch (InstantiationException e) {
            throw new NoBugException("entityToModel : 实例化异常", e);
        } catch (IllegalAccessException e) {
            throw new NoBugException("entityToModel : 安全权限异常", e);
        }
        // 转换
        BeanUtils.copyProperties(entity, model);
        return model;
    }

    /**
     * 将实体类F类型的集合 转换成实体类T类型的集合
     *
     * @param fromList 实体类F类型的集合
     * @param tClass   实体类T的class
     * @return 实体类T类型的集合
     */
    public static <F, T> List<T> entityListToModelList(List<F> fromList, Class<T> tClass) {
        if (listIsEmpty(fromList) || isEmpty(tClass)) {
            return null;
        }
        // 通过JAVA8 流的形式进行转换
        return fromList.stream().map(i -> entityToModel(i, tClass)).collect(Collectors.toList());
    }

    /**
     * 将实体类F类型的分页对象 转换成实体类T类型的分页对象
     *
     * @param iPage  实体类F类型的分页对象
     * @param tClass 实体类T的class
     * @return 实体类T类型的分页对象
     */
    public static <F, T> IPage<T> entityPageToModelPage(IPage<F> iPage, Class<T> tClass) {
        if (iPage == null || isEmpty(tClass)) {
            return null;
        }
        IPage<T> tPage = new Page<>();
        // 首先转换对象
        BeanUtils.copyProperties(iPage, tPage);
        if (listIsEmpty(iPage.getRecords())) {
            // 如果数据为空则直接返回
            return tPage;
        }
        // 再转换分页对象内数据的类型
        tPage.setRecords(entityListToModelList(iPage.getRecords(), tClass));
        return tPage;
    }

    /**
     * 获取请求的IP地址
     *
     * @param request 请求
     * @return IP地址
     */
    public static String getIpAddressByRequest(HttpServletRequest request) {
        String ip = request.getHeader(X_FORWARDED_FOR);
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader(PROXY_CLIENT_IP);
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader(WL_PROXY_CLIENT_IP);
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
